package com.ruoyi.app.business.login;

import com.ruoyi.app.business.code.CheckCodeBusiness;
import com.ruoyi.app.config.context.UserInfoContextHolder;
import com.ruoyi.app.converter.UserConverter;
import com.ruoyi.app.domain.user.LoginUserInfo;
import com.ruoyi.common.core.enums.YesNoEnum;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.core.utils.pwd.PwdUtil;
import com.ruoyi.service.user.entity.UserEntity;
import com.ruoyi.service.user.enums.UserStatusEnum;
import com.ruoyi.service.user.model.UserInfoModel;
import com.ruoyi.service.user.service.UserService;
import java.time.LocalDateTime;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class LoginBusiness {

  @Resource
  private UserService userService;
  @Resource
  private TokenBusiness tokenBusiness;
  @Resource
  private CheckCodeBusiness checkCodeBusiness;

  /**
   * 数据转换器
   */
  final UserConverter userConverter = UserConverter.INSTANCE;

  /**
   * 手机号码登录
   *
   * @param phone     手机号码
   * @param checkCode 验证码
   * @return 登录信息
   */
  public LoginUserInfo loginByMobile(String phone, String checkCode, String userType) {
    //1 验证码校验
    checkCodeBusiness.checkCode(phone, checkCode);
    //2 根据手机号获得用户信息
    final UserEntity userEntity = CommonUtils.requireNotNull(
        userService.getUserInfoByMobile(phone, userType), "用户信息有误[手机号码未注册或者已注销]");
    //校验用户状态
    CommonUtils.assertsTrueWithMessage(UserStatusEnum.PASSED.eqCode(userEntity.getStatus()),
        "用户尚未审核通过,请联系管理员");
    return doLogin(userEntity);
  }

  /**
   * 用户名密码登录
   *
   * @param userName 用户名
   * @param password 密码
   * @param userType 用户类型
   * @return 登录信息
   */
  public LoginUserInfo loginByNamePwd(String userName, String password, String userType) {
    final UserEntity userEntity = CommonUtils.requireNotNull(
        userService.getByUserNameAndPwd(userName, PwdUtil.encode(password), userType),
        "账号或者密码错误");
    //校验用户状态
    CommonUtils.assertsTrueWithMessage(UserStatusEnum.PASSED.eqCode(userEntity.getStatus()),
        "用户尚未审核通过,请联系管理员");
    return doLogin(userEntity);
  }

  public LoginUserInfo refreshToken(String token) {
    final UserInfoModel loginUser = tokenBusiness.getLoginUser(token);
    final String newToken = tokenBusiness.refreshToken(token);
    LoginUserInfo loginUserInfo = UserConverter.INSTANCE.toUserLogin(loginUser);
    loginUserInfo.setToken(newToken);
    return loginUserInfo;
  }

  public void checkTokenBuildContext(HttpServletRequest request) {
    tokenBusiness.checkToken(request);
    final UserInfoModel loginUser = tokenBusiness.getLoginUser(request);
    if (YesNoEnum.YES.eqCode(loginUser.getDelFlag())) {
      throw new RuntimeException("用户已被注销");
    }
    UserInfoContextHolder.set(loginUser);
  }

  private LoginUserInfo doLogin(UserEntity userEntity) {
    //处理登录信息,生成token
    //刷新用户登录信息
    //用户最后登录IP,时间
    userEntity.setLoginIp(IpUtils.getIpAddr()).setLoginTime(LocalDateTime.now());
    //调成异步模式
    userService.updateById(userEntity);
    final LoginUserInfo loginInfo = userConverter.toUserLogin(userEntity);
    loginInfo.setToken(tokenBusiness.createToken(userEntity));
    return loginInfo;
  }


}
